
import { Model, QueryTypes } from "sequelize";
import { sequelize } from "../lib/database.js";
import { BaseDataMapper } from "./base-mapper.js";
import { z } from 'zod'
import logger from "../lib/log4js.js";
export class EvaProjectUserMapper extends BaseDataMapper {

    private seed: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789";
    constructor() {
        super("EvaProjectUser");

    }

    async findOwnedUser(project_id: string, test: boolean) {
        logger.debug("[mapper]:" + project_id)
        const sql = `
            select 
                epo.owner_name_name,
                epo.plan_quantity,
                epo.project_id,
                epo.id project_owner_id,
                ifnull(jepu.logined,0) logined,
                ifnull(jepu.submited,0) submited
                from     eva_project_owner epo
                left join (
                    select sum(is_login) logined,sum(is_submit) submited,project_owner_id 
                    from eva_project_user epu
                    where epu.is_test=? and epu.project_id=?
                    group by epu.project_owner_id
                ) jepu on jepu.project_owner_id= epo.id
                where epo.project_id =?`;
        const result = await sequelize.query(sql, {
            replacements: [test ? 1 : 0, project_id, project_id],
            type: QueryTypes.SELECT
        })
        return result;
    }
    /***
     * 生成该项目内所有主体的用户，重新生成将使以前用户及投票失效
     * @param project_id id of project,must
     * @param p_project_owner_id id of project_owner, optional
     * @param p_amount number of added tickets of previous param(p_project_owner_id)
     * @returns generated ownered user list
     */
    async generateOwnedUsers(
        project_id: string,
        p_project_owner_id: string | undefined,
        p_amount: number | 0,
        user_only: boolean | false,
        test: boolean | false
    ) {
        const { customAlphabet } = await import('nanoid');
        const p_own_condition = p_project_owner_id ? ` and epo.id='${p_project_owner_id}'` : '';
        const sql = `
            select 
                epo.project_id ,
                epo.id project_owner_id ,
                epof.ru_form_id project_owner_form_id ,
                epof.ru_form_name ,
                epo.owner_name_name,
                epo.plan_quantity,
                epof.user_type 
                from  eva_project_owner epo 
            inner join eva_project_owner_form epof 
                on epof.project_id = epo.project_id 
                and epof.project_owner_id  = epo.id 
                where epo.project_id =? ${p_own_condition}
            group by epo.project_id ,epo.id
        `;

        const result: any = await sequelize.query(sql, {
            replacements: [project_id],
            type: QueryTypes.SELECT
        });
        if (!result || result.length === 0) {
            return []
        }
        let generated_users: any[] = [];
        const records = [];
        for (const { project_id, project_owner_id, owner_name_name, plan_quantity, user_type } of result) {
            if (!project_id || !project_owner_id || (p_project_owner_id && p_project_owner_id !== project_owner_id)) continue;
            const whparam = { where: { project_id, project_owner_id, is_test: test ? 1 : 0 } };
            if (!p_project_owner_id || user_only) {
                this.remove(whparam);
            }
            const pam: number = parseInt(plan_quantity);
            const amount = p_project_owner_id ? (p_amount > 0 ? p_amount : pam) : pam;
            if (amount === 0) continue;
            for (let i = 0; i < amount; i++) {
                const userId = customAlphabet(this.seed, 10)();
                const userCode = userId.substring(2, 6);
                records.push(
                    {
                        project_id,
                        project_owner_id,
                        project_owner_name: owner_name_name,
                        name: userId,
                        code: userCode,
                        is_login: 0,
                        is_submit: 0,
                        user_type,
                        is_test: test
                    }
                )
            }
        }
        if (records.length === 0) return []
        const modes: Model[] = await this.saveBatch({ records });
        generated_users = generated_users.concat(modes.map(m => m.dataValues));
        return generated_users;
    }
    async findCheckedUser(project_id: string, project_owner_id: string, name: string) {

        const validForm = z.object({
            project_id: z.string({ message: "缺少项目" }),
            project_owner_id: z.string({ message: "缺少主体信息" }),
            name: z.string({ message: "缺少用户信息" })
        }).safeParse({ project_id, project_owner_id, name });
        if (!validForm.success) {
            return {
                message: validForm.error.issues.map(i => i.message).join(",")
            }
        }

        const sql = `          
                select 
                    ep.object_group_name group_name,
                    DATEDIFF(NOW(),ep.start_time) startDelta,
                    DATEDIFF(ep.end_time,NOW()) endDelta, 
                    epu.project_owner_name name,
                    on2.remark,
                    epu.is_login ,
                    epu.is_submit,                    
                    ep.is_start,
                    epu.is_test, 
                    epu.code 
                from 
                    eva_project_user epu 
                inner join eva_project ep on ep.id =epu.project_id    
                inner join eva_project_owner epo on epo.id=epu.project_owner_id
                inner join owner_name on2 on on2.id = epo.owner_name_id
                where epu.project_id=? 
                    and epu.project_owner_id =? 
                    and epu.name =?                  
        `
        let result: any;
        try {
            result = await sequelize.query(sql, {
                replacements: [project_id, project_owner_id, name],
                type: QueryTypes.SELECT
            });
        } catch (error) {
            logger.debug(result);
            logger.error(error);
        }

        if (!result || result.length === 0) {
            return {
                message: '主体信息错误,请扫描正确的二维码'
            }
        }
        if (result[0].startDelta < 0 || result[0].endDelta < 0 || result[0].is_start === 0) {
            return {
                message: '投票时间已过期/未开始'
            }
        }
        return result[0];
    }

}
